﻿//Created by Action Script Viewer - http://www.buraks.com/asv
package Engine.Classes {
    import Engine.Interfaces.*;
    import flash.display.*;
    import flash.geom.*;
    import Engine.Helpers.*;
    import flash.utils.*;
    import Engine.*;
    import com.adobe.utils.*;

    public class CollisionMap {

        protected static const COLLISIONMAP_COLOR:uint = 16729156;
        protected static const COLLISIONMAP_ALPHA:Number = 0.6;

        private static var m_ignoreObjectsInCollision:Array;

        protected var m_width:int;
        protected var m_height:int;
        protected var m_cells:Array = null;
        protected var m_visualCollisionMap:Sprite;
        protected var m_pathfinder:Pathfinder;
		
		// 地图两个顶点的坐标
        protected var m_xStart:int;
        protected var m_xEnd:int;
        protected var m_yStart:int;
        protected var m_yEnd:int;

        public function CollisionMap(){
            if (m_ignoreObjectsInCollision == null){
                m_ignoreObjectsInCollision = new Array();
            };
        }
        public static function compareCollisionFlags(_arg1:int, _arg2:int):Boolean{
            var _local3:Boolean;
            if (((_arg2 & Constants.COLLISION_AVATAR) << 0) == Constants.COLLISION_AVATAR){
                if (((_arg1 & Constants.COLLISION_ALL_EXCEPT_AVATAR) << 0) == Constants.COLLISION_ALL_EXCEPT_AVATAR){
                    _local3 = false;
                };
            };
            if ((((((_arg1 & Constants.COLLISION_OVERLAP) << 0) == Constants.COLLISION_OVERLAP)) && ((((_arg2 & Constants.COLLISION_OVERLAP) << 0) == Constants.COLLISION_OVERLAP)))){
                _local3 = false;
            };
            if ((((((_arg2 & Constants.COLLISION_SAME_ONLY) << 0) == Constants.COLLISION_SAME_ONLY)) && (!((((_arg1 & Constants.COLLISION_SAME_ONLY) << 0) == Constants.COLLISION_SAME_ONLY))))){
                _local3 = false;
            };
            return (_local3);
        }
        public static function getIgnoredCollisionObjects():Array{
            return (CollisionMap.m_ignoreObjectsInCollision);
        }

        public function dispose():void{
            var _local2:int;
            var _local1:int = this.m_xStart;
            while (_local1 < this.m_xEnd) {
                _local2 = this.m_yStart;
                while (_local2 < this.m_yEnd) {
                    (this.m_cells[_local1][_local2] as CollisionCell).dispose();
                    this.m_cells[_local1][_local2] = null;
                    _local2++;
                };
                _local1++;
            };
        }
		
        public function initialize(_arg1:int, _arg2:int, _arg3:Boolean=true):void{
            this.initRect(0, 0, _arg1, _arg2, _arg3);
        }
		
		/**
		 * 初始化整个地图的CollisonCell
		 */
        public function initRect(_arg1:int, _arg2:int, _arg3:int, _arg4:int, _arg5:Boolean=true):void{
            var _local7:int;
            this.m_xStart = _arg1;
            this.m_yStart = _arg2;
            this.m_xEnd = (_arg1 + _arg3);
            this.m_yEnd = (_arg2 + _arg4);
            this.m_width = _arg3;
            this.m_height = _arg4;
            this.m_cells = new Array(_arg3);
            var _local6:int = this.m_xStart;
            while (_local6 < this.m_xEnd) {
                this.m_cells[_local6] = new Array(_arg4);
                _local7 = this.m_yStart;
                while (_local7 < this.m_yEnd) {
                    this.m_cells[_local6][_local7] = new CollisionCell(_local6, _local7);
                    _local7++;
                };
                _local6++;
            };
            if (_arg5){
                this.m_pathfinder = new Pathfinder(this.m_width, this.m_height, this);
            };
        }
		
		/**
		 * 往CollisionMap中插入一个Object, 主要是更新cell的存得对象已经周围cell的wall里存得对象 
		 */
        public function insertObject(_arg1:WorldObject):void{
            var _local2:Vector3;
            var _local3:int;
            var _local4:int;
            var _local5:int;
            var _local6:int;
            var _local7:int;
            var _local8:int;
            var _local9:int;
            var _local10:int;
            var _local11:Number;
            var _local12:Number;
            var _local13:int;
            var _local14:int;
            var _local15:CollisionCell;
            var _local16:Array;
            if (_arg1.isCollidable()){
                _local2 = _arg1.getSizeNoClone();
                _local3 = Constants.DIRECTION_NE;
                _local4 = Constants.DIRECTION_NW;
                _local5 = Constants.DIRECTION_SE;
                _local6 = Constants.DIRECTION_SW;
                _local7 = _arg1.getPositionNoClone().x;
                _local8 = _arg1.getPositionNoClone().y;
                _local9 = (_local7 + _local2.x);
                _local10 = (_local8 + _local2.y);
                _local11 = _local2.x;
                _local12 = _local2.y;
                _local9 = ((_local9 > this.m_xEnd)) ? this.m_xEnd : ((_local9 < this.m_xStart)) ? this.m_xStart : _local9;
                _local10 = ((_local10 > this.m_yEnd)) ? this.m_yEnd : ((_local10 < this.m_yStart)) ? this.m_yStart : _local10;
                _local7 = ((_local7 > this.m_xEnd)) ? this.m_xEnd : ((_local7 < this.m_xStart)) ? this.m_xStart : _local7;
                _local8 = ((_local8 > this.m_yEnd)) ? this.m_yEnd : ((_local8 < this.m_yStart)) ? this.m_yStart : _local8;
                if ((((_local11 > 0)) && ((_local12 > 0)))){
                    _local13 = _local7;
                    while (_local13 < _local9) {
                        _local16 = this.m_cells[_local13];
                        _local14 = _local8;
                        while (_local14 < _local10) {
                            _local15 = _local16[_local14];
							
                            _local15.addObject(_arg1);
							
                            if (_local13 > this.m_xStart){
                                _local15.setWall(_local6, _arg1);
                                CollisionCell(this.m_cells[(_local13 - 1)][_local14]).setWall(_local3, _arg1);
                            };
                            if (_local14 > this.m_yStart){
                                _local15.setWall(_local5, _arg1);
                                CollisionCell(_local16[(_local14 - 1)]).setWall(_local4, _arg1);
                            };
                            _local14++;
                        };
                        _local13++;
                    };
                } else {
                    _local13 = _local7;
                    while (_local13 <= _local9) {
                        _local16 = this.m_cells[_local13];
                        _local14 = _local8;
                        while (_local14 <= _local10) {
                            if ((((_local14 < _local10)) && ((_local11 == 0)))){
                                CollisionCell(_local16[_local14]).setWall(_local6, _arg1);
                                if (_local13 > this.m_xStart){
                                    CollisionCell(this.m_cells[(_local13 - 1)][_local14]).setWall(_local3, _arg1);
                                };
                            };
                            if ((((_local13 < _local9)) && ((_local12 == 0)))){
                                CollisionCell(_local16[_local14]).setWall(_local5, _arg1);
                                if (_local14 > this.m_yStart){
                                    CollisionCell(_local16[(_local14 - 1)]).setWall(_local4, _arg1);
                                };
                            };
                            _local14++;
                        };
                        _local13++;
                    };
                };
                if (this.m_pathfinder != null){
					// 设置这个区域没法通过了
                    this.m_pathfinder.setCollisionMapDirty(_local7, _local9, _local8, _local10);
                };
            };
            if (this.m_visualCollisionMap){
                this.drawCollisionMap(this.m_visualCollisionMap);
            };
        }
        public function setTerrain(_arg1:ITerrainMap):void{
            var _local5:int;
            var _local6:int;
            var _local7:int;
            var _local8:int;
            var _local9:Array;
            var _local10:int;
            var _local2:int = (this.m_width / _arg1.width);
            var _local3:int = (this.m_height / _arg1.height);
            var _local4:int;
            while (_local4 < _arg1.width) {
                _local5 = 0;
                while (_local5 < _arg1.height) {
                    if (_arg1.isPathable(_local4, _local5)){
                        _local6 = (_local4 * _local2);
                        _local7 = (_local5 * _local3);
                        _local8 = 0;
                        while (_local8 < _local2) {
                            _local9 = this.m_cells[(_local6 + _local8)];
                            _local10 = 0;
                            while (_local10 < _local3) {
                                CollisionCell(_local9[(_local7 + _local10)]).isPathable = true;
                                if (this.m_pathfinder != null){
                                    this.m_pathfinder.setPathable((_local6 + _local8), (_local7 + _local10));
                                };
                                _local10++;
                            };
                            _local8++;
                        };
                    };
                    _local5++;
                };
                _local4++;
            };
        }
        public function isPositionPathable(_arg1:int, _arg2:int):Boolean{
            return (CollisionCell(this.m_cells[_arg1][_arg2]).isPathable);
        }
        public function isValidCellPos(_arg1:int, _arg2:int):Boolean{
            return ((((((((_arg1 >= this.m_xStart)) && ((_arg1 < this.m_xEnd)))) && ((_arg2 >= this.m_yStart)))) && ((_arg2 < this.m_yEnd))));
        }
        public function removeObject(_arg1:WorldObject):void{
            var _local2:Vector3;
            var _local3:Vector3;
            var _local4:Number;
            var _local5:Number;
            var _local6:Number;
            var _local7:Number;
            var _local8:int;
            var _local9:Array;
            var _local10:int;
            if (((_arg1.isCollidable()) && (_arg1.isAttached()))){
                _local2 = _arg1.getAttachSize();
                _local3 = _arg1.getAttachPosition();
                _local4 = (_local3.x - 1);
                _local5 = (_local3.y - 1);
                _local6 = ((_local3.x + _local2.x) + 1);
                _local7 = ((_local3.y + _local2.y) + 1);
                _local6 = ((_local6 > this.m_xEnd)) ? this.m_xEnd : ((_local6 < this.m_xStart)) ? this.m_xStart : _local6;
                _local7 = ((_local7 > this.m_yEnd)) ? this.m_yEnd : ((_local7 < this.m_yStart)) ? this.m_yStart : _local7;
                _local4 = ((_local4 > this.m_xEnd)) ? this.m_xEnd : ((_local4 < this.m_xStart)) ? this.m_xStart : _local4;
                _local5 = ((_local5 > this.m_yEnd)) ? this.m_yEnd : ((_local5 < this.m_yStart)) ? this.m_yStart : _local5;
                _local8 = _local4;
                while (_local8 < _local6) {
                    _local9 = this.m_cells[_local8];
                    _local10 = _local5;
                    while (_local10 < _local7) {
                        CollisionCell(_local9[_local10]).removeObject(_arg1);
                        _local10++;
                    };
                    _local8++;
                };
                if (this.m_pathfinder != null){
                    this.m_pathfinder.setCollisionMapDirty(_local4, _local6, _local5, _local7);
                };
            };
            if (this.m_visualCollisionMap){
                this.drawCollisionMap(this.m_visualCollisionMap);
            };
        }
        public function ignoreObjectForSession(_arg1:WorldObject):void{
            CollisionMap.m_ignoreObjectsInCollision.push(_arg1);
        }
        public function checkCollision(_arg1:CollisionLookup, _arg2:WorldObject=null):Boolean{
            var _local3:Boolean;
            if (_arg1.isLine()){
                _local3 = this.checkCollisionForLine(_arg1);
            } else {
                _local3 = this.checkCollisionForBox(_arg1, _arg2);
            };
            return (_local3);
        }
        protected function checkCollisionForBox(_arg1:CollisionLookup, _arg2:WorldObject=null):Boolean{
            var _local6:int;
            var _local7:CollisionCell;
            var _local3:Boolean;
            var _local4 = (_arg1.colliders == null);
            var _local5:int = _arg1.startX;
            while (_local5 < _arg1.endX) {
                _local6 = _arg1.startY;
                while (_local6 < _arg1.endY) {
                    if (((this.isValidCellPos(_local5, _local6)) && (this.isPositionPathable(_local5, _local6)))){
                        _local7 = this.m_cells[_local5][_local6];
                        if (_arg1.startY < _local6){
                            _local3 = ((this.addCollidersToResults(_local5, _local6, _local7.getWalls(Constants.DIRECTION_SE), _arg1)) || (_local3));
                            if (((_local3) && (_local4))){
                                break;
                            };
                        };
                        if (_arg1.startX < _local5){
                            _local3 = ((this.addCollidersToResults(_local5, _local6, _local7.getWalls(Constants.DIRECTION_SW), _arg1)) || (_local3));
                            if (((_local3) && (_local4))){
                                break;
                            };
                        };
                        _local3 = ((this.addCollidersToResults(_local5, _local6, _local7.items, _arg1, _arg2)) || (_local3));
                        if (((_local3) && (_local4))){
                            break;
                        };
                        if (((_local3) && (_local4))){
                            return (_local3);
                        };
                    } else {
                        _local3 = true;
                        if (_local4){
                            return (_local3);
                        };
                    };
                    _local6++;
                };
                _local5++;
            };
            return (_local3);
        }
        public function checkCollisionForCell(_arg1:CollisionLookup):Boolean{
            var _local2:Boolean;
            var _local3:CollisionCell = this.m_cells[_arg1.startX][_arg1.startY];
            _local2 = this.addCollidersToResults(_arg1.startX, _arg1.startY, _local3.items, _arg1, null);
            return (_local2);
        }
        protected function checkCollisionForLine(_arg1:CollisionLookup):Boolean{
            var _local3:Array;
            var _local4:int;
            var _local5:int;
            var _local6:CollisionCell;
            var _local2:Boolean;
            var _local7 = (_arg1.colliders == null);
            if (_arg1.startX == _arg1.endX){
                _local4 = _arg1.startX;
                _local5 = _arg1.startY;
                while (_local5 < _arg1.endY) {
                    if (this.isValidCellPos(_local4, _local5)){
                        _local6 = this.m_cells[_local4][_local5];
                        _local3 = _local6.getWalls(Constants.DIRECTION_SW);
                        _local2 = ((this.addCollidersToResults(_local4, _local5, _local3, _arg1)) || (_local2));
                        if (((_local2) && (_local7))){
                            break;
                        };
                    } else {
                        if (this.isValidCellPos((_local4 - 1), _local5)){
                            _local6 = this.m_cells[(_local4 - 1)][_local5];
                            _local3 = _local6.getWalls(Constants.DIRECTION_NE);
                            _local2 = ((this.addCollidersToResults(_local4, _local5, _local3, _arg1)) || (_local2));
                            if (((_local2) && (_local7))){
                                break;
                            };
                        };
                    };
                    _local5++;
                };
            } else {
                _local5 = _arg1.startY;
                _local4 = _arg1.startX;
                while (_local4 < _arg1.endX) {
                    if (this.isValidCellPos(_local4, _local5)){
                        _local6 = this.m_cells[_local4][_local5];
                        _local3 = _local6.getWalls(Constants.DIRECTION_SE);
                        _local2 = ((this.addCollidersToResults(_local4, _local5, _local3, _arg1)) || (_local2));
                        if (((_local2) && (_local7))){
                            break;
                        };
                    } else {
                        if (this.isValidCellPos(_local4, (_local5 - 1))){
                            _local6 = this.m_cells[_local4][(_local5 - 1)];
                            _local3 = _local6.getWalls(Constants.DIRECTION_NW);
                            _local2 = ((this.addCollidersToResults(_local4, _local5, _local3, _arg1)) || (_local2));
                            if (((_local2) && (_local7))){
                                break;
                            };
                        };
                    };
                    _local4++;
                };
            };
            return (_local2);
        }
        private function addCollidersToResults(_arg1:int, _arg2:int, _arg3:Array, _arg4:CollisionLookup, _arg5:WorldObject=null):Boolean{
            var _local9:WorldObject;
            var _local10:Boolean;
            var _local11:Vector3;
            var _local12:int;
            var _local13:int;
            var _local14:Boolean;
            var _local15:Boolean;
            var _local6:Boolean;
            var _local7:int = _arg4.getFlags(_arg1, _arg2);
            var _local8:int;
            while (_local8 < _arg3.length) {
                _local9 = (_arg3[_local8] as WorldObject);
                _local10 = (((_arg4.ignoreObjects == null)) || ((_arg4.ignoreObjects.indexOf(_local9) == -1)));
                if (((_local10) && (!((_local9 == _arg5))))){
                    _local11 = _local9.getPositionNoClone();
                    _local12 = (_arg1 - _local11.x);
                    _local13 = (_arg2 - _local11.y);
                    _local14 = ((!((_local9 == null))) && (_local9.checkInternalCollision(_local12, _local13, _local7)));
                    _local15 = ((!((_local9 == null))) && (((_arg4.colliderTypes & _local9.getObjectType()) > 0)));
                    if (((_local14) && (_local15))){
                        _local6 = true;
                        if (_arg4.colliders != null){
                            if (_arg4.colliders.indexOf(_local9) == -1){
                                _arg4.colliders.push(_local9);
                            };
                        } else {
                            break;
                        };
                    };
                };
                _local8++;
            };
            return (_local6);
        }
        public function showCollisionMap(_arg1:Boolean):void{
            if ((((this.m_visualCollisionMap == null)) && (_arg1))){
                this.m_visualCollisionMap = new Sprite();
                this.drawCollisionMap(this.m_visualCollisionMap);
                GlobalEngine.viewport.overlayBase.addChild(this.m_visualCollisionMap);
            } else {
                if (((!((this.m_visualCollisionMap == null))) && (!(_arg1)))){
                    if (this.m_visualCollisionMap.parent){
                        this.m_visualCollisionMap.parent.removeChild(this.m_visualCollisionMap);
                    };
                    this.m_visualCollisionMap = null;
                };
            };
        }
        public function drawCollisionMap(_arg1:Sprite):void{
            var _local6:int;
            var _local7:CollisionCell;
            var _local8:Point;
            var _local2:Graphics = _arg1.graphics;
            var _local3:Point = IsoMath.getPixelDeltaFromTileDelta(1, 0);
            var _local4:Point = IsoMath.getPixelDeltaFromTileDelta(0, 1);
            _local2.clear();
            var _local5:int = this.m_xStart;
            while (_local5 < this.m_xEnd) {
                _local6 = this.m_yStart;
                while (_local6 < this.m_yEnd) {
                    _local7 = (this.m_cells[_local5][_local6] as CollisionCell);
                    _local8 = IsoMath.tilePosToPixelPos(_local5, _local6);
                    if (_local7.items.length){
                        _local2.lineStyle(0, 0, 0);
                        _local2.moveTo(_local8.x, _local8.y);
                        _local2.beginFill(COLLISIONMAP_COLOR, COLLISIONMAP_ALPHA);
                        _local2.lineTo((_local8.x + _local3.x), (_local8.y + _local3.y));
                        _local2.lineTo(((_local8.x + _local3.x) + _local4.x), ((_local8.y + _local3.y) + _local4.y));
                        _local2.lineTo((_local8.x + _local4.x), (_local8.y + _local4.y));
                        _local2.endFill();
                    };
                    _local2.lineStyle(4, COLLISIONMAP_COLOR);
                    if (_local7.getWalls(Constants.DIRECTION_SW).length > 0){
                        _local2.moveTo(_local8.x, _local8.y);
                        _local2.lineTo((_local8.x + _local4.x), (_local8.y + _local4.y));
                    };
                    if (_local7.getWalls(Constants.DIRECTION_SE).length > 0){
                        _local2.moveTo(_local8.x, _local8.y);
                        _local2.lineTo((_local8.x + _local3.x), (_local8.y + _local3.y));
                    };
                    if (_local7.getWalls(Constants.DIRECTION_NE).length > 0){
                        _local2.moveTo((_local8.x + _local3.x), (_local8.y + _local3.y));
                        _local2.lineTo(((_local8.x + _local3.x) + _local4.x), ((_local8.y + _local3.y) + _local4.y));
                    };
                    if (_local7.getWalls(Constants.DIRECTION_NW).length > 0){
                        _local2.moveTo((_local8.x + _local4.x), (_local8.y + _local4.y));
                        _local2.lineTo(((_local8.x + _local3.x) + _local4.x), ((_local8.y + _local3.y) + _local4.y));
                    };
                    _local6++;
                };
                _local5++;
            };
        }
        public function getObjectsByPosition(_arg1:int, _arg2:int):Array{
            var _local4:CollisionCell;
            var _local3:Array = [];
            if (this.isValidCellPos(_arg1, _arg2)){
                _local4 = this.m_cells[_arg1][_arg2];
                _local3 = _local4.items.concat([]);
            };
            return (_local3);
        }
        public function findCoordinatesForObject(_arg1:WorldObject):Array{
            var _local2:CollisionCell;
            var _local3:WorldObject;
            var _local5:String;
            var _local6:String;
            var _local7:String;
            var _local4:Array = new Array();
            _local4[0] = -1;
            _local4[1] = -1;
            for (_local5 in this.m_cells) {
                for (_local6 in this.m_cells[_local5]) {
                    _local2 = this.m_cells[_local5][_local6];
                    for (_local7 in _local2.items) {
                        _local3 = _local2.items[_local7];
                        if ((_local3 as WorldObject) == _arg1){
                            _local4[0] = _local2.x;
                            _local4[1] = _local2.y;
                            return (_local4);
                        };
                    };
                };
            };
            return (_local4);
        }
        public function getIntersectingObjects(_arg1:Box3D):Array{
            var _local5:int;
            var _local6:CollisionCell;
            var _local7:WorldObject;
            var _local2:Dictionary = new Dictionary();
            var _local3:int = _arg1.min.x;
            while (_local3 < _arg1.max.x) {
                _local5 = _arg1.min.y;
                while (_local5 < _arg1.max.y) {
                    if (this.isValidCellPos(_local3, _local5)){
                        _local6 = this.m_cells[_local3][_local5];
                        for each (_local7 in _local6.items) {
                            if (_local2[_local7] == null){
                                _local2[_local7] = _local7;
                            };
                        };
                    };
                    _local5++;
                };
                _local3++;
            };
            var _local4:Array = DictionaryUtil.getKeys(_local2);
            return (_local4);
        }
        public function getPath(_arg1:Vector3, _arg2:Vector3, _arg3:Array=null, _arg4:Boolean=false, _arg5:Number=0.1, _arg6:Array=null, _arg7:WorldObject=null, _arg8:Boolean=false):Boolean{
            var _local9:Boolean;
            if (this.m_pathfinder != null){
                if (_arg6 == null){
                    _arg6 = [];
                };
                _arg2.x = Utilities.clamp(_arg2.x, this.m_xStart, (this.m_xEnd - 1));
                _arg2.y = Utilities.clamp(_arg2.y, this.m_yStart, (this.m_yEnd - 1));
                _local9 = this.m_pathfinder.findPath(_arg1.x, _arg1.y, _arg2.x, _arg2.y, _arg6, _arg3, _arg8, _arg5);
            };
            return (_local9);
        }
        public function findFirstAvailableCoordsForBox(_arg1:int, _arg2:int):Array{
            var _local3:Array = new Array();
            _local3[0] = -1;
            _local3[1] = -1;
            var _local4:int = (this.m_width / 2);
            var _local5:int = (this.m_width / 2);
            var _local6:int;
            var _local7 = 1;
            var _local8:int;
            var _local9:CollisionLookup = new CollisionLookup();
            while ((((((((_local4 < this.m_xEnd)) && ((_local4 >= this.m_xStart)))) && ((_local5 < this.m_yEnd)))) && ((_local5 >= this.m_yStart)))) {
                _local9.startX = _local4;
                _local9.endX = (_local4 + _arg1);
                _local9.startY = _local5;
                _local9.endY = (_local5 + _arg2);
                if (!this.checkCollision(_local9)){
                    _local3[0] = _local4;
                    _local3[1] = _local5;
                    return (_local3);
                };
                if (_local6 == 0){
                    _local5--;
                } else {
                    if (_local6 == 1){
                        _local4--;
                    } else {
                        if (_local6 == 2){
                            _local5 = (_local5 + 1);
                        } else {
                            if (_local6 == 3){
                                _local4 = (_local4 + 1);
                            };
                        };
                    };
                };
                _local8 = (_local8 + 1);
                if (_local8 >= _local7){
                    _local6 = (_local6 + 1);
                    _local6 = (_local6 % 4);
                    _local8 = 0;
                    if ((((_local6 == 0)) || ((_local6 == 2)))){
                        _local7 = (_local7 + 1);
                    };
                };
            };
            return (_local3);
        }

    }
}//package Engine.Classes 

class CollisionWall {

    public var x:int;
    public var y:int;
    public var walls:Array;

    public function CollisionWall(_arg1:int, _arg2:int){
        this.walls = [];
        super();
        this.x = _arg1;
        this.y = _arg2;
    }
}
